/*********************************************************************
 * Clase de utilidad. Fuente de partículas (Lineales y Radiales) 
 * Programación Multimedia y Juegos
 * Autor: David Vallejo Fernández    david.vallejo@tegnix.com
 * Autor: Carlos González Morcillo   carlos.gonzalez@tegnix.com
 *
 * You can redistribute and/or modify this file under the terms of the
 * GNU General Public License ad published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * and later version. See <http://www.gnu.org/licenses/>.
 *
 * This file is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.  
 *********************************************************************/

package graphics;

import aze.display.TileSprite;
import aze.display.TileLayer;

enum PType {
  Linear;
  Radial;
}

class ParticleSource {
  public var _x:Float;           // Posición de la fuente de particulas
  public var _y:Float;

  var _root:TileLayer;           // Capa principal de dibujado
  var _id:String;                // Grafico para la particula
  var _pList:Array<TileSprite>;  // Lista de graficos (1 por particula)

  var _time:Float;               // Tiempo desde la ultima particula
  var _npart:Int;                // Numero de particulas a lanzar
  var _spart:Int;                // Numero de particulas lanzadas
  var _interval:Float;           // Intervalo de tiempo entre particulas

  var _type:PType;               // Tipo del sistema de particulas

  // Constructor =====================================================
  public function new(id:String, layer:TileLayer, 
		      posX:Float, posY:Float, type:PType) {
    _id = id; _x = posX; _y = posY; _root = layer; _type = type;
    _pList = new Array<TileSprite>();

    _time = 0; _npart = 0; _spart = 0;  _interval = 0;
  }

  // getNParticles ===================================================
  public function getNParticles():Int {
    return _pList.length;
  }

  // Actualizacion de particulas =====================================
  public function clearParticles() {
    for (p in _pList) {
      _root.removeChild(p);
    }
    _pList.splice(0,_pList.length);
  }

  // Añadir una particula a la lista =================================
  function addIndividualParticle():Void {
    _time = 0;
    var p = new TileSprite(_id); 
    p.alpha = 0.5; p.scale = 0.25;
    p.x = _x; p.y = _y;
    _pList.push(p);
    _root.addChild(p);
    _spart++;
  }

  public function addParticles(nparticles: Int, interval: Int = 0) {
    clearParticles();
    _time = 0; _spart = 0;  _npart = nparticles; _interval = interval; 
    switch (_type) {
    case Linear: addIndividualParticle();
    case Radial:
      for (i in 0 ... _npart) addIndividualParticle();
    }
  }

  public function setPosition(posX:Float, posY:Float):Void {
    _x = posX; _y = posY;
  }

  // Actualizacion de particulas =====================================
  function updateParticleList():Void {
    for (p in _pList) {
      if (p.alpha > 0) {
	switch (_type) {
	case Linear: 
	  p.alpha -= .01;
	  p.scale *= 1.04;
	case Radial: 
	  p.x += 6 - Std.random(12);
	  p.y += 6 - Std.random(12);
	  p.alpha -= .02;
	  p.scale *= 1.04;
	}
      }
      else {
	_root.removeChild(p);
	_pList.remove(p);
      }
    }
  }

  public function update(w:Int, h:Int, eTime:Int):Void { 
    _time += eTime;
    if ((_type == Linear) && (_time > _interval) 
	&& (_spart < _npart)) {   // + partículas?
      addIndividualParticle();
    }
    updateParticleList();
  }

}